package cfca.seal.util;

import cfca.sadk.org.bouncycastle.asn1.ASN1Encodable;
import cfca.sadk.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import cfca.sadk.org.bouncycastle.asn1.DERIA5String;
import cfca.sadk.org.bouncycastle.asn1.DERPrintableString;
import cfca.sadk.org.bouncycastle.asn1.DERT61String;
import cfca.sadk.org.bouncycastle.asn1.DERUTF8String;
import cfca.sadk.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import cfca.sadk.org.bouncycastle.asn1.x500.RDN;
import cfca.sadk.org.bouncycastle.asn1.x500.X500Name;
import cfca.sadk.org.bouncycastle.asn1.x500.X500NameStyle;
import cfca.sadk.org.bouncycastle.asn1.x500.style.AbstractX500NameStyle;
import cfca.sadk.org.bouncycastle.asn1.x500.style.IETFUtils;
import cfca.sadk.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import java.util.Hashtable;

public class CFCAStyle extends AbstractX500NameStyle
{
  public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6");

  public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10");

  public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11");

  public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12");

  public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3");

  public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5");

  public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9");

  public static final ASN1ObjectIdentifier SERIALNUMBER = SN;

  public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7");

  public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8");

  public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4");
  public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42");
  public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43");
  public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44");
  public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45");

  public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier("2.5.4.15");

  public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier("2.5.4.17");

  public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier("2.5.4.46");

  public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier("2.5.4.65");

  public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.1");

  public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.2");

  public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.3");

  public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.4");

  public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.5");

  public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14");

  public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16");

  public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54");

  public static final ASN1ObjectIdentifier TELEPHONE_NUMBER = X509ObjectIdentifiers.id_at_telephoneNumber;

  public static final ASN1ObjectIdentifier NAME = X509ObjectIdentifiers.id_at_name;

  public static final ASN1ObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress;

  public static final ASN1ObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName;
  public static final ASN1ObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress;

  public static final ASN1ObjectIdentifier E = EmailAddress;

  public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25");

  public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1");
  static final String jurisdictionOfIncorporation = "1.3.6.1.4.1.311.60.2.1";
  public static final ASN1ObjectIdentifier jurisdictionOfIncorporationLocalityName = new ASN1ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.1");
  public static final ASN1ObjectIdentifier jurisdictionOfIncorporationStateOrProvinceName = new ASN1ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.2");
  public static final ASN1ObjectIdentifier jurisdictionOfIncorporationCountryName = new ASN1ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.3");

  private static final Hashtable DefaultSymbols = new Hashtable();

  private static final Hashtable DefaultLookUp = new Hashtable();
  protected final Hashtable defaultLookUp;
  protected final Hashtable defaultSymbols;
  private boolean useUTF8String = false;

  public static final X500NameStyle INSTANCE = new CFCAStyle();

  public static final X500NameStyle UTF8_INSTANCE = new CFCAStyle(true);

  public static final X500NameStyle SM2_INSTANCE = UTF8_INSTANCE;

  protected CFCAStyle()
  {
    this.defaultSymbols = copyHashTable(DefaultSymbols);
    this.defaultLookUp = copyHashTable(DefaultLookUp);
  }

  protected CFCAStyle(boolean useUTF8String)
  {
    this.defaultSymbols = copyHashTable(DefaultSymbols);
    this.defaultLookUp = copyHashTable(DefaultLookUp);

    this.useUTF8String = useUTF8String;
  }

  protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
  {
    if (oid.equals(EmailAddress))
      return new DERIA5String(value);
    if (oid.equals(C))
      return new DERPrintableString(value);
    if (this.useUTF8String)
      return new DERUTF8String(value);
    if (canBePrintable(value)) {
      if (value.indexOf("@") != -1) {
        return new DERT61String(value);
      }
      return new DERPrintableString(value);
    }

    return super.encodeStringValue(oid, value);
  }

  private boolean canBePrintable(String str)
  {
    for (int i = str.length() - 1; i >= 0; i--) {
      if (str.charAt(i) > '') {
        return false;
      }
    }
    return true;
  }

  public String oidToDisplayName(ASN1ObjectIdentifier oid) {
    return (String)DefaultSymbols.get(oid);
  }

  public String[] oidToAttrNames(ASN1ObjectIdentifier oid) {
    return IETFUtils.findAttrNamesForOID(oid, this.defaultLookUp);
  }

  public ASN1ObjectIdentifier attrNameToOID(String attrName) {
    return IETFUtils.decodeAttrName(attrName, this.defaultLookUp);
  }

  public RDN[] fromString(String dirName) {
    return IETFUtils.rDNsFromString(dirName, this);
  }

  public String toString(X500Name name) {
    StringBuffer buf = new StringBuffer();
    boolean first = true;

    RDN[] rdns = name.getRDNs();

    for (int i = 0; i < rdns.length; i++) {
      if (first)
        first = false;
      else {
        buf.append(',');
      }

      IETFUtils.appendRDN(buf, rdns[i], this.defaultSymbols);
    }

    return buf.toString();
  }

  static
  {
    DefaultSymbols.put(C, "C");
    DefaultSymbols.put(O, "O");
    DefaultSymbols.put(T, "T");
    DefaultSymbols.put(OU, "OU");
    DefaultSymbols.put(CN, "CN");
    DefaultSymbols.put(L, "L");
    DefaultSymbols.put(ST, "ST");
    DefaultSymbols.put(SN, "SERIALNUMBER");
    DefaultSymbols.put(EmailAddress, "E");
    DefaultSymbols.put(DC, "DC");
    DefaultSymbols.put(UID, "UID");
    DefaultSymbols.put(STREET, "STREET");
    DefaultSymbols.put(SURNAME, "SURNAME");
    DefaultSymbols.put(GIVENNAME, "GIVENNAME");
    DefaultSymbols.put(INITIALS, "INITIALS");
    DefaultSymbols.put(GENERATION, "GENERATION");
    DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress");
    DefaultSymbols.put(UnstructuredName, "unstructuredName");
    DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier");
    DefaultSymbols.put(DN_QUALIFIER, "DN");
    DefaultSymbols.put(PSEUDONYM, "Pseudonym");
    DefaultSymbols.put(POSTAL_ADDRESS, "PostalAddress");
    DefaultSymbols.put(NAME_AT_BIRTH, "NameAtBirth");
    DefaultSymbols.put(COUNTRY_OF_CITIZENSHIP, "CountryOfCitizenship");
    DefaultSymbols.put(COUNTRY_OF_RESIDENCE, "CountryOfResidence");
    DefaultSymbols.put(GENDER, "Gender");
    DefaultSymbols.put(PLACE_OF_BIRTH, "PlaceOfBirth");
    DefaultSymbols.put(DATE_OF_BIRTH, "DateOfBirth");
    DefaultSymbols.put(POSTAL_CODE, "PostalCode");
    DefaultSymbols.put(BUSINESS_CATEGORY, "BusinessCategory");
    DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber");
    DefaultSymbols.put(NAME, "Name");

    DefaultSymbols.put(jurisdictionOfIncorporationLocalityName, "jurisdictionOfIncorporationLocalityName");
    DefaultSymbols.put(jurisdictionOfIncorporationStateOrProvinceName, "jurisdictionOfIncorporationStateOrProvinceName");
    DefaultSymbols.put(jurisdictionOfIncorporationCountryName, "jurisdictionOfIncorporationCountryName");

    DefaultLookUp.put("c", C);
    DefaultLookUp.put("o", O);
    DefaultLookUp.put("t", T);
    DefaultLookUp.put("ou", OU);
    DefaultLookUp.put("cn", CN);
    DefaultLookUp.put("l", L);

    DefaultLookUp.put("s", ST);
    DefaultLookUp.put("st", ST);
    DefaultLookUp.put("sn", SN);
    DefaultLookUp.put("serialnumber", SN);
    DefaultLookUp.put("street", STREET);
    DefaultLookUp.put("emailaddress", E);
    DefaultLookUp.put("dc", DC);
    DefaultLookUp.put("e", E);
    DefaultLookUp.put("uid", UID);
    DefaultLookUp.put("surname", SURNAME);
    DefaultLookUp.put("givenname", GIVENNAME);
    DefaultLookUp.put("initials", INITIALS);
    DefaultLookUp.put("generation", GENERATION);
    DefaultLookUp.put("unstructuredaddress", UnstructuredAddress);
    DefaultLookUp.put("unstructuredname", UnstructuredName);
    DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER);
    DefaultLookUp.put("dn", DN_QUALIFIER);
    DefaultLookUp.put("pseudonym", PSEUDONYM);
    DefaultLookUp.put("postaladdress", POSTAL_ADDRESS);
    DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH);
    DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP);
    DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE);
    DefaultLookUp.put("gender", GENDER);
    DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH);
    DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH);
    DefaultLookUp.put("postalcode", POSTAL_CODE);
    DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY);
    DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER);
    DefaultLookUp.put("name", NAME);

    DefaultLookUp.put("jurisdictionofincorporationlocalityname", jurisdictionOfIncorporationLocalityName);
    DefaultLookUp.put("jurisdictionofincorporationstateorprovincename", jurisdictionOfIncorporationStateOrProvinceName);
    DefaultLookUp.put("jurisdictionofincorporationcountryname", jurisdictionOfIncorporationCountryName);
  }
}